package impl

// 此文件是用来定义实现接口中结构体

import (
	"context"

	"gitee.com/liuxiaowei123/vblog-3/app/user"
	"gitee.com/liuxiaowei123/vblog-3/conf"
	"gitee.com/liuxiaowei123/vblog-3/exception"
	"gitee.com/liuxiaowei123/vblog-3/ioc"
	"gorm.io/gorm"
)

// 用来约束对象，实现接口
var _ user.UserService = &UserServiceImpl{}

type UserServiceImpl struct {
	// 需要实现数据保存到数据库，所以依赖数据库
	db *gorm.DB // gorm.DB 是GORM库中的一个核心类型，代表了数据库的连接和操作
}

func NewUserServiceImpl() *UserServiceImpl {
	return &UserServiceImpl{
		// Debug() 表示开启数据库操作的调试模式，在调试模式下，数据库连接可能会记录更多的信息
		db: conf.C.Mysql.Getconn().Debug(),
	}
}

// 把UserServiceImpl对象注册到ioc中
func init() {
	// 错误代码：ioc.Controller().Registry(ioc.Controller().Get(user.Appname))
	ioc.Controller().Registry(&UserServiceImpl{})
}

// UserServiceImpl对象实现Object接口函数，完成初始化
func (u *UserServiceImpl) Init() {
	u.db = conf.C.Mysql.Getconn().Debug()
}

// UserServiceImpl对象实现Object接口函数
func (u *UserServiceImpl) Name() string {
	return user.Appname
}

// 创建用户
func (u *UserServiceImpl) CreateUser(c context.Context, req *user.CreateUserRequest) (*user.User, error) {
	//1、校验参数：避免输入的用户、密码为空
	// if req.Username == "" || req.Password == "" {
	// 	return nil, fmt.Errorf("请输入用户名或密码")
	// }
	if err := req.Validate(); err != nil {
		return nil, err
	}

	// 把明文密码加密
	req.PasswordHash()

	//2、创建用户，就是构造一个User实例
	ins := user.NewUser(req)

	//3、保存用户到数据库
	err := u.db.WithContext(c).Create(ins).Error
	if err != nil {
		return nil, err
	}
	//4、返回用户
	return ins, nil
}

// 查询用户
func (u *UserServiceImpl) DescribeUser(c context.Context, req *user.DescribeUserRequest) (*user.User, error) {
	// 1、定义一个User结构体实例
	ins := user.NewUser(user.NewCreateUserRequest())

	// 2、判断查询逻辑
	query := u.db.WithContext(c)
	switch req.DescribeBy {
	case user.DESCRIBE_BY_ID:
		query = query.Where("id = ?", req.DescribeValue)
	case user.DESCRIBE_BY_USERNAME:
		query = query.Where("username = ?", req.DescribeValue)
	}

	// 3、执行查询
	err := query.First(ins).Error
	if err != nil {
		return nil, exception.NewNotFound("没有查询到username或id=%s的用户", req.DescribeValue)
	}

	// 4、返回结果
	return ins, nil
}

// 删除用户
func (u *UserServiceImpl) DeleteUser(c context.Context, req *user.DeleteUserRequest) error {
	// 1、查询用户
	describereq := user.NewDescribeByID(req.ID)
	ins, err := u.DescribeUser(c, describereq)
	if err != nil {
		panic(err)
	}

	// 2、删除用户
	err = u.db.WithContext(c).Delete(ins).Error
	if err != nil {
		panic(err)
	}

	return nil
}
